home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / Tools / mpeg_stat-2.2 / readfile.c < prev    next >
C/C++ Source or Header  |  1995-05-10  |  30KB  |  1,081 lines

  1. /*
  2.  * Copyright (c) 1995 The Regents of the University of California.
  3.  * All rights reserved.
  4.  * 
  5.  * Permission to use, copy, modify, and distribute this software and its
  6.  * documentation for any purpose, without fee, and without written agreement is
  7.  * hereby granted, provided that the above copyright notice and the following
  8.  * two paragraphs appear in all copies of this software.
  9.  * 
  10.  * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
  11.  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
  12.  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
  13.  * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  14.  * 
  15.  * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
  16.  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
  17.  * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
  18.  * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
  19.  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  20.  */
  21.  
  22. #include "video.h"
  23. #include "proto.h"
  24. #include <sys/types.h>
  25. #include <signal.h>
  26. #ifndef MIPS
  27. #include <netinet/in.h>
  28. #else
  29. #include <bsd/netinet/in.h>
  30. #endif
  31.  
  32. #include "util.h"
  33. #include "dither.h"
  34. #include "opts.h"
  35.  
  36. #ifdef __SAVE_DECODED_FILE__
  37. static FILE *hackOutput;
  38. #endif
  39.  
  40. /* 
  41.   Are we a system layer parser or pure video?
  42.   (-1 is uninit, 0 is video, 1 is sys_layer)
  43. */
  44. int sys_layer=-1;
  45. /* Keep track of bytes parsed in system layer */
  46. int audBytes,vidBytes,sysBytes;
  47.  
  48. /* End of File flag. */
  49. extern int EOF_flag;
  50.  
  51. /* Global file pointer to incoming data. */
  52. extern FILE *input;
  53.  
  54. /* Options to control logging */
  55. extern FILE *syslogOutput;
  56. extern int opts;
  57.   
  58.   
  59. /*
  60.  *--------------------------------------------------------------
  61.  *
  62.  * get_more_data --
  63.  *
  64.  *    Called by get_more_data to read in more data from
  65.  *      video MPG files (non-system-layer)
  66.  *
  67.  * Results:
  68.  *    Input buffer updated, buffer length updated.
  69.  *      Returns 1 if data read, 0 if EOF, -1 if error.
  70.  *
  71.  * Side effects:
  72.  *      None.
  73.  *
  74.  *--------------------------------------------------------------
  75.  */
  76. int 
  77.   get_more_data(bs_ptr, max_length, length_ptr, buf_ptr)
  78. unsigned int **bs_ptr;
  79. int *max_length, *length_ptr;
  80. unsigned int **buf_ptr;
  81. {
  82.   static BOOLEAN swap;
  83.   int ioBytes, data, result;
  84.   unsigned int *mark;
  85.   
  86.   if (sys_layer==0) {
  87.     return pure_get_more_data(*bs_ptr, *max_length, length_ptr, buf_ptr, swap);
  88.   }
  89.   if (sys_layer==-1) {
  90.     /* Time to init ourselves */
  91.     swap=(htonl(1)!=1);
  92.     mark=*bs_ptr;
  93.     ioBytes=fread(&data,1,4,input);
  94.     if (ioBytes!=4) return 0;
  95.     data=ntohl(data);
  96.     if ((data==PACK_START_CODE) || (data==SYSTEM_HEADER_START_CODE)) {
  97.       /* Yow, a System Layer Stream.  Much harder to parse.  Call in the
  98.      specialist.... */
  99.       fprintf(stderr,"This is an MPEG System Layer Stream.  ");
  100.       fprintf(stderr,"Audio is not analyzed.\n");
  101.       sys_layer=1;
  102.       init_read_sys();
  103.       result= read_sys(bs_ptr, max_length, length_ptr, buf_ptr, data);
  104. #ifdef __SAVE_DECODED_FILE__
  105.       fwrite((unsigned char *)(*buf_ptr),1,*length_ptr*4,hackOutput);
  106. #endif
  107.       return result;
  108.     } else {
  109.       /* No system Layer junk, just pretent we didn't peek,
  110.      and hereafter just call pure_get_more_data */
  111.       sys_layer=0;
  112.       **bs_ptr=data;
  113.       *length_ptr=1;
  114.       result= pure_get_more_data(*bs_ptr, *max_length, 
  115.                  length_ptr, buf_ptr, swap);
  116.       *buf_ptr=*bs_ptr;
  117.       return result;
  118.     }}
  119.   /* A system layer stream (called after the 1st time), call the specialist */
  120. #ifdef __SAVE_DECODED_FILE__
  121.   data=*length_ptr;
  122. #endif
  123.   result=read_sys(bs_ptr, max_length, length_ptr, buf_ptr, 0);
  124. #ifdef __SAVE_DECODED_FILE__
  125.   fwrite((unsigned char *) ((*buf_ptr)+data),1,4*((*length_ptr)-data),hackOutput);
  126. #endif
  127.   return result;
  128. }
  129. /*
  130.  *--------------------------------------------------------------
  131.  *
  132.  * pure_get_more_data --
  133.  *      (get_more_data from ver 2.0 with swap added)
  134.  *
  135.  *    Called by get_more_data to read in more data from
  136.  *      video MPG files (non-system-layer)
  137.  *
  138.  * Results:
  139.  *    Input buffer updated, buffer length updated.
  140.  *      Returns 1 if data read, 0 if EOF, -1 if error.
  141.  *
  142.  * Side effects:
  143.  *      None.
  144.  *
  145.  *--------------------------------------------------------------
  146.  */
  147.  
  148. int 
  149.   pure_get_more_data(buf_start, max_length, length_ptr, buf_ptr, swap)
  150. unsigned int *buf_start;
  151. int max_length;
  152. int *length_ptr;
  153. unsigned int **buf_ptr;
  154. BOOLEAN swap;
  155. {
  156.   
  157.   int length, num_read, i, request;
  158.   unsigned char *buffer, *mark;
  159.   unsigned int *lmark;
  160.   
  161.   if (EOF_flag) return 0;
  162.   
  163.   length = *length_ptr;
  164.   buffer = (unsigned char *) *buf_ptr;
  165.   
  166.   if (length > 0) {
  167.     memcpy((unsigned char *) buf_start, buffer, (length*4));
  168.     mark = ((unsigned char *) (buf_start + length));
  169.   }
  170.   else {
  171.     mark = (unsigned char *) buf_start;
  172.     length = 0;
  173.   }
  174.   
  175.   request = (max_length-length)*4;
  176.   
  177.   
  178.   num_read = fread( mark, 1, request, input);
  179.   
  180.   /* Paulo Villegas - 26/1/1993: Correction for 4-byte alignment */
  181.   {
  182.     int num_read_rounded;
  183.     unsigned char *index;
  184.     
  185.     num_read_rounded = 4*(num_read/4);
  186.     
  187.     /* this can happen only if num_read<request; i.e. end of file reached */
  188.     if( num_read_rounded < num_read )
  189.       { 
  190.      num_read_rounded = 4*( num_read/4+1 );
  191.      /* fill in with zeros */
  192.      for( index=mark+num_read; index<mark+num_read_rounded; *(index++)=0 );
  193.      /* advance to the next 4-byte boundary */
  194.      num_read = num_read_rounded;
  195.       }
  196.   }
  197.   
  198.   if   (num_read < 0) {
  199.     return -1;
  200.   }
  201.   else if (num_read == 0) {
  202.     *buf_ptr = buf_start;
  203.     
  204.     /* Make 32 bits after end equal to 0 and 32
  205.        bits after that equal to seq end code
  206.        in order to prevent messy data from infinite
  207.        recursion.
  208.        */
  209.     
  210.     *(buf_start + length) = 0x0;
  211.     *(buf_start + length+1) = SEQ_END_CODE;
  212.     
  213.     EOF_flag = 1;
  214.     return 0;
  215.   }
  216.   
  217.   lmark = (unsigned int *) mark;
  218.   
  219.   num_read = num_read/4;
  220.   
  221.   if (swap) {
  222.     for (i=0; i<num_read; i++) {
  223.       *lmark = htonl(*lmark);
  224.       lmark++;
  225.     }
  226.   }
  227.   
  228.   *buf_ptr = buf_start;
  229.   *length_ptr = length + num_read;
  230.   
  231.   return 1;
  232. }
  233.  
  234.  
  235.  
  236.  
  237. /* 
  238.   Here is the specialist.... 
  239.   Code is adapted from our program demux....
  240.   A bunch of this needs to be #ifdef ANALYSIS'ed
  241.   define __SYSREAD_LOGGING_ON__ to get  an output file for debugging
  242.   */
  243.  
  244.  
  245. /* Stream IDs */
  246. static int gAudioStreamID;
  247. static int gVideoStreamID;
  248. static int gReservedStreamID;
  249.  
  250. #ifdef ANALYSIS
  251. /* Statistics */
  252. static int gNumAudioPackets;
  253. static int gNumVideoPackets;
  254. static int gNumPaddingPackets;
  255. static int gNumReservedPackets;
  256. static int gNumPrivate_1_Packets;
  257. static int gNumPrivate_2_Packets;
  258. #endif
  259.  
  260. /*
  261.  *----------------------------------------------------------
  262.  *
  263.  *  init_read_sys
  264.  *
  265.  *      Called before read_sys is used to parse the file.
  266.  *      Currently only sets up the logging file (when defined)
  267.  *
  268.  *  Results:  None
  269.  *
  270.  *  Side Effects: Zeros Byte counts, opens Hack Output if needed
  271.  *
  272.  *----------------------------------------------------------
  273.  */
  274. void init_read_sys() {
  275. #ifdef __SAVE_DECODED_FILE__
  276.   hackOutput = fopen("hack.vid", "w");
  277.   if (hackOutput == NULL) {
  278.     fprintf(stderr, "Can't open output file \"hack.vid\"\n");
  279.     exit(1);
  280.   }
  281. #endif
  282.   audBytes=0; vidBytes=0; sysBytes=0;
  283. }
  284.  
  285.  
  286. /*
  287.  *----------------------------------------------------------
  288.  *
  289.  *  read_sys
  290.  *
  291.  *      Parse out a packet of the system layer MPEG file.
  292.  *
  293.  *  Results:  Returns 0 if error or EOF
  294.  *            Returns 1 if more data read (could be just one int)
  295.  *
  296.  *  Side Effects:  ReadPacket can change *bs_ptr to be a new buffer
  297.  *                 buf_ptr will remain pointing at *length_ptr (at input)
  298.  *                         into the buffer
  299.  *                 *length_ptr will be changed to the new size
  300.  *                 *max_length can be changed if a new buffer is alloc'd
  301.  *
  302.  *----------------------------------------------------------
  303.  */
  304. int read_sys(bs_ptr, max_length, length_ptr, buf_ptr, start)
  305.      unsigned int **bs_ptr;
  306.      int *max_length, *length_ptr;
  307.      unsigned int **buf_ptr, start;  
  308.      /* start is either a start code or 0 to indicate continued parsing */
  309. {
  310.   unsigned int startCode;
  311.   int errorCode, PacketReply;
  312.   unsigned char packetID;
  313.   double systemClockTime;
  314.   unsigned long muxRate;
  315.   /* Statistics */
  316.   static int numPacks = 0;
  317.   static int numPackets = 0;
  318.   static int numSystemHeaders = 0;
  319.   static BOOLEAN Parse_done=FALSE;
  320.   BOOLEAN match;
  321.   
  322.   if (!start) {
  323.     errorCode = ReadStartCode(&startCode);
  324.     if (EOF_flag) return 0;
  325.     if (errorCode != 0) {
  326.       fprintf(stderr, "Unable to read initial pack start code\n");
  327.       return 0;
  328.     }}
  329.   else {
  330.     errorCode = 0;
  331.     startCode = start;
  332.   }
  333.   
  334.   while (1) {
  335.     match=FALSE;
  336.     if (startCode == PACK_START_CODE) {
  337.       ++numPacks; match=TRUE;
  338.       if (opts&SYSLAYER_LOG) {
  339.     fprintf(syslogOutput, "PACK #%d:\n", numPacks);
  340.       }
  341.       errorCode = ReadPackHeader( &systemClockTime, &muxRate);
  342.       if (errorCode != 0) {
  343.     fprintf(stderr, "Error in reading pack header\n");
  344.     return 0;
  345.       }
  346.       errorCode = ReadStartCode( &startCode);
  347.       if (errorCode != 0) {
  348.     fprintf(stderr, "Error in reading start code\n");
  349.     return 0;
  350.       }
  351.     }
  352.     if (startCode == SYSTEM_HEADER_START_CODE) {
  353.       if (opts&SYSLAYER_LOG) {
  354.     fprintf(syslogOutput, "SYSTEM HEADER:\n");
  355.       }
  356.       ++numSystemHeaders; match=TRUE;
  357.       errorCode = ReadSystemHeader();
  358.       if (errorCode != 0) {
  359.     fprintf(stderr, "Error in reading system header\n");
  360.     return 0;
  361.       }
  362.       errorCode = ReadStartCode( &startCode);
  363.       if (errorCode != 0) {
  364.     fprintf(stderr,"Error in reading start code after system header\n");
  365.     return 0;
  366.       }
  367.     }
  368.     packetID = startCode & 0xff;
  369.     while (((startCode & PACKET_START_CODE_MASK) == PACKET_START_CODE_PREFIX) &&
  370.        (packetID>=0xbc)) {
  371.       ++numPackets; match=TRUE;
  372.       packetID = startCode & 0xff;
  373.       if (opts&SYSLAYER_LOG) {
  374.     fprintf(syslogOutput, "PACKET ID %02x:\n", packetID);
  375.       }
  376.       PacketReply = ReadPacket(packetID, bs_ptr, max_length, length_ptr, buf_ptr);
  377.       switch (PacketReply) {
  378.       case 2: 
  379.     return 1;
  380.       case 1: 
  381.     if (opts&SYSLAYER_LOG) {
  382.       fprintf(syslogOutput, "Problems in ReadPacket, returning partial.\n");
  383.     }
  384.     return 0;
  385.       default: /* do nothing */
  386.     break;
  387.       }
  388.       errorCode = ReadStartCode( &startCode);
  389.       if (errorCode != 0) {
  390.     fprintf(stderr,"Error in start code after packet\n");
  391.     return 0;
  392.       }
  393.       if (startCode == PACK_START_CODE || startCode == ISO_11172_END_CODE)
  394.     break;
  395.     }
  396.     if (startCode == ISO_11172_END_CODE) {
  397.       match=TRUE;
  398.       if (Parse_done) return 1;
  399. #ifdef ANALYSIS
  400.       fprintf(stderr, "Successful parse of MPEG system level\n");
  401.       fprintf(stderr, "%d system headers, %d packs, %d packets\n",
  402.           numSystemHeaders, numPacks, numPackets);
  403.       fprintf(stderr, "%d audio packets, %d video packets, %d padding packets\n",
  404.           gNumAudioPackets, gNumVideoPackets, gNumPaddingPackets);
  405.       fprintf(stderr, "%d reserved packets, %d/%d private type 1/2 packets\n",
  406.           gNumReservedPackets, gNumPrivate_1_Packets, gNumPrivate_2_Packets);
  407. #endif
  408.       ReadPacket(NOT_PACKET_ID, bs_ptr, max_length, length_ptr, buf_ptr);
  409.       Parse_done=TRUE;
  410.       return 1;
  411.     }
  412.     if (errorCode != 0)
  413.       return 1;
  414.     if (!match) {
  415.       fprintf(stderr,"\nNo match found for start code %08x in system layer, skipping\n",startCode);
  416.       if (opts&SYSLAYER_LOG)
  417.     fprintf(syslogOutput, "Error with start code %08x, did not match at %d\n",
  418.         startCode, (int) ftell(input));  
  419.       startCode=(int) find_start_code();
  420.       if (opts&SYSLAYER_LOG) {
  421.     if (startCode==EOF) 
  422.       fprintf(syslogOutput, "Found EOF in find_start_code\n");
  423.     else fprintf(syslogOutput, "Found %08x at %d\n",
  424.              startCode, (int) ftell(input));  
  425.       }
  426.       if (startCode==EOF) {
  427.     EOF_flag=1;
  428.     return 0;
  429.       }
  430.     }
  431.   }
  432.   return 0; /* shouldnt get here */
  433. }
  434.  
  435. /*
  436.  *-----------------------------------------------------------
  437.  *
  438.  *  ReadStartCode
  439.  *
  440.  *      Parses a start code out of the stream
  441.  *
  442.  *  Results/Side Effects:  Sets *startCode to the code, returns
  443.  *     1 on error, 0 on success
  444.  *
  445.  *-----------------------------------------------------------
  446.  */
  447. int ReadStartCode(startCode)
  448.      unsigned int *startCode;
  449. {
  450.   int numRead;
  451.   
  452.   numRead = fread((unsigned char *)startCode, 1, 4, input);
  453.   *startCode=htonl(*startCode);
  454.   
  455.   if (numRead < 4) {
  456.     if ((opts&SYSLAYER_LOG)&&(EOF_flag==0)) {
  457.       fprintf(syslogOutput, "Error in reading start code, only got %d bytes\n", 
  458.               numRead);
  459.     }
  460.     EOF_flag=1;
  461.     return 1;
  462.   }
  463.   if (opts&SYSLAYER_LOG) {
  464.     fprintf(syslogOutput, "Read as start code: %08x\n", *startCode);
  465.   }
  466.   if ((*startCode&0xfffffe00) != 0) {
  467.     int start_pos;
  468.     fprintf(stderr,"Problem with system layer parse, skipping to start code\n");
  469.     if (opts&SYSLAYER_LOG) {
  470.       start_pos = (int) ftell(input);
  471.       fprintf(syslogOutput, "Error with start code, not a start code! at %d\n",
  472.           start_pos);  
  473.     }
  474.     *startCode=(int) find_start_code();
  475.     if (*startCode==EOF) {
  476.       if (opts&SYSLAYER_LOG) {
  477.     fprintf(syslogOutput, "Skipped all the way to EOF!\n");
  478.     }
  479.       EOF_flag=TRUE;
  480.       return 0;
  481.     }
  482.     if (opts&SYSLAYER_LOG) {
  483.       int end_pos=(int) ftell(input);
  484.       fprintf(syslogOutput, "Found %08x at %d, skipped over %d bytes.\n",
  485.           *startCode, end_pos, end_pos-start_pos);
  486.     }
  487.   }
  488.   sysBytes+=4;
  489.   return 0;
  490. }
  491.  
  492. /*
  493.  *-----------------------------------------------------------
  494.  *
  495.  *  find_start_code
  496.  *
  497.  *      Parses a start code out of the stream by tossing bytes until it gets one
  498.  *
  499.  *  Results/Side Effects:  Parses bytes of the stream, returns code
  500.  *                         Returns EOF in case of end of file
  501.  *
  502.  *-----------------------------------------------------------
  503.  */
  504. int find_start_code()
  505. {
  506.  NO_ZEROS:
  507.   switch(fgetc(input)) {
  508.   case 0:    goto ONE_ZERO;
  509.   case EOF:  goto EOF_FOUND;
  510.   default:   goto NO_ZEROS;
  511.   }
  512.  
  513.  ONE_ZERO:
  514.   switch(fgetc(input)) {
  515.   case 0:    goto TWO_ZEROS;
  516.   case EOF:  goto EOF_FOUND;
  517.   default:   goto NO_ZEROS;
  518.   }
  519.  
  520.  TWO_ZEROS:
  521.   switch(fgetc(input)) {
  522.   case 0x01:  goto CODE_FOUND;
  523.   case 0x00:  goto TWO_ZEROS;
  524.   case EOF:  goto EOF_FOUND;
  525.   default:    goto NO_ZEROS;
  526.   }
  527.  
  528.  CODE_FOUND:
  529.   return 0x00000100+fgetc(input);
  530.  
  531.  EOF_FOUND:   /* received EOF */
  532.   return EOF;
  533. }
  534.  
  535.  
  536.  
  537. /*
  538.  *-----------------------------------------------------------------
  539.  *
  540.  *  ReadPackHeader
  541.  *
  542.  *      Parses out the PACK header
  543.  *
  544.  *  Returns: 1 on error, 0 on success
  545.  *
  546.  *-------------------------------------------------------------------
  547.  */
  548. int ReadPackHeader(systemClockTime,muxRate)
  549.      double *systemClockTime;
  550.      unsigned long *muxRate;
  551. {
  552.   int numRead;
  553.   unsigned char inputBuffer[PACK_HEADER_SIZE];
  554.   unsigned long systemClockRef;
  555.   unsigned char systemClockRefHiBit;
  556.   int errorCode;
  557.   
  558.   numRead = fread(inputBuffer, 1, PACK_HEADER_SIZE, input);
  559.   if (numRead < PACK_HEADER_SIZE) {
  560.     EOF_flag=1;
  561.     if (opts&SYSLAYER_LOG) {
  562.       fprintf(syslogOutput, 
  563.               "Error in reading Pack header, only got %d bytes\n", numRead);
  564.     }
  565.     return 1;
  566.   }
  567.   sysBytes+=numRead;
  568.   ReadTimeStamp(inputBuffer, &systemClockRefHiBit, &systemClockRef);
  569.   errorCode = MakeFloatClockTime(systemClockRefHiBit, systemClockRef, 
  570.                  systemClockTime);
  571.   ReadRate(&inputBuffer[5], muxRate);
  572.   *muxRate *= MUX_RATE_SCALE_FACTOR;
  573.   if (opts&SYSLAYER_LOG) {
  574.     fprintf(syslogOutput, "\tSystem clock reference: %d, %lu (0x%x%08x)\n",
  575.         (int)systemClockRefHiBit, systemClockRef,
  576.         (int)systemClockRefHiBit, systemClockRef);
  577.     if (errorCode == 0) {
  578.       fprintf(syslogOutput, "\tSystem clock time: %1.4lf\n", *systemClockTime);
  579.     } else {
  580.       fprintf(syslogOutput, "Error reading system clock time\n");
  581.     }
  582.     fprintf(syslogOutput, "\tmuxRate: %lu (0x%08x)\n", *muxRate, *muxRate);
  583.   }
  584.   return 0;
  585. }
  586.  
  587. /*
  588.  *------------------------------------------------------------------
  589.  *
  590.  *   ReadSystemHeader
  591.  *
  592.  *      Parse out the system header, setup out dtream IDs for parsing packets
  593.  *
  594.  *   Results:  Returns 1 on error, 0 on success.
  595.  *             Sets gAudioStreamID and gVideoStreamID
  596.  *
  597.  *------------------------------------------------------------------
  598.  */
  599. int ReadSystemHeader()
  600.   unsigned char *inputBuffer = NULL;
  601.   int numRead;
  602.   int pos,i;
  603.   unsigned short headerSize;
  604.   unsigned char streamID;
  605.   /* Only needed for system log file */
  606.   unsigned long rateBound;
  607.   unsigned long audioBound;
  608.   unsigned char fixedFlag;
  609.   unsigned char cspsFlag;
  610.   unsigned long videoBound;
  611.   unsigned char sysAudioLockFlag;
  612.   unsigned char sysVideoLockFlag;
  613.   unsigned char stdBufferScale;
  614.   unsigned long stdBufferSize;
  615.   
  616.   numRead = fread((char *)&headerSize, 1, 2, input); 
  617.   headerSize=ntohs(headerSize);
  618.   if (numRead != 2) {
  619.     EOF_flag=1;
  620.     if (opts&SYSLAYER_LOG) {
  621.       fprintf(syslogOutput, 
  622.               "error in reading System header size, only got %d bytes\n", 
  623.               numRead);
  624.     }
  625.     return 1;
  626.   }
  627.   inputBuffer = (unsigned char *) malloc(headerSize+1);
  628.   sysBytes+=headerSize;
  629.   if (inputBuffer == NULL) {
  630.     if (opts&SYSLAYER_LOG) {
  631.       fprintf(syslogOutput, 
  632.               "error in allocating %d bytes\n", headerSize);
  633.     }
  634.     return 1;
  635.   }
  636.   inputBuffer[headerSize]=0;
  637.   numRead = fread(inputBuffer, 1, headerSize, input); 
  638.   if (opts&SYSLAYER_LOG) {
  639.     for(i=0;i<headerSize;i++) 
  640.       fprintf(syslogOutput, 
  641.               "%x ",*(inputBuffer+i));
  642.     fprintf(syslogOutput,"\n");
  643.   }
  644.   if (numRead < headerSize) {
  645.     EOF_flag=1;
  646.     if (opts&SYSLAYER_LOG) {
  647.       fprintf(syslogOutput, 
  648.               "error in reading System Header, only got %d bytes\n", 
  649.               numRead);
  650.     }
  651.     return 1;
  652.   }
  653.   if (opts&SYSLAYER_LOG) {
  654.     ReadRate(&inputBuffer[0], &rateBound);
  655.     rateBound *= MUX_RATE_SCALE_FACTOR;
  656.     fprintf(syslogOutput, "\trate_bound: %lu (0x%08x)\n", rateBound, rateBound);
  657.     audioBound = (unsigned long)inputBuffer[3] >> 2;
  658.     fprintf(syslogOutput, "\taudio_bound: %lu (0x%08x)\n", audioBound, audioBound);
  659.     fixedFlag = (inputBuffer[3] >> 1) & 0x01;
  660.     fprintf(syslogOutput, "\tfixed_flag: %d\n", fixedFlag);
  661.     cspsFlag = inputBuffer[3] & 0x01;
  662.     fprintf(syslogOutput, "\tCSPS_flag: %d\n", cspsFlag);
  663.     videoBound = (unsigned long)inputBuffer[4] & 0x1f;
  664.     fprintf(syslogOutput, "\tvideo_bound: %lu (0x%08x)\n", videoBound, videoBound);
  665.     sysAudioLockFlag = (inputBuffer[4] & 0x80) >> 7;
  666.     fprintf(syslogOutput, "\tsystem_audio_lock_flag: %d\n", sysAudioLockFlag);
  667.     sysVideoLockFlag = (inputBuffer[4] & 0x40) >> 6;
  668.     fprintf(syslogOutput, "\tsystem_video_lock_flag: %d\n", sysVideoLockFlag);
  669.   }
  670.   
  671.   pos = 6;
  672.   while ((inputBuffer[pos] & 0x80) == 0x80) {
  673.     streamID = inputBuffer[pos];
  674.     if (opts&SYSLAYER_LOG) {
  675.       ReadSTD(&inputBuffer[pos + 1], &stdBufferScale, &stdBufferSize);
  676.       fprintf(syslogOutput, 
  677.               "\tRead STD_buffer_scale = %d, STD_buffer_size = %lu (0x%0x)\n",
  678.               (int)stdBufferScale, stdBufferSize, stdBufferSize);
  679.       fprintf(syslogOutput, "\tSystem Header: stream with ID 0x%x\n", streamID); 
  680.     }
  681.     switch (streamID) {
  682.     case STD_VIDEO_STREAM_ID: 
  683.       if (opts&SYSLAYER_LOG) {
  684.     fprintf(syslogOutput, "\tSystem Header: Std video stream\n");
  685.       }
  686.       break;
  687.     case STD_AUDIO_STREAM_ID: 
  688.       if (opts&SYSLAYER_LOG) {
  689.     fprintf(syslogOutput, "\tSystem Header: Std audio stream\n");
  690.       }
  691.       break;
  692.     case RESERVED_STREAM_ID: 
  693.       if (opts&SYSLAYER_LOG) {
  694.     fprintf(syslogOutput, "\tSystem Header: Reserved stream\n");
  695.       }
  696.       break;
  697.     case PADDING_STREAM_ID: 
  698.       if (opts&SYSLAYER_LOG) {
  699.     fprintf(syslogOutput, "\tSystem Header: Padding stream\n");
  700.       }
  701.       break;
  702.     case PRIVATE_STREAM_1_ID: 
  703.       if (opts&SYSLAYER_LOG) {
  704.     fprintf(syslogOutput, "\tSystem Header: Private (1) stream\n");
  705.       }
  706.       break;
  707.     case PRIVATE_STREAM_2_ID: 
  708.       if (opts&SYSLAYER_LOG) {
  709.     fprintf(syslogOutput, "\tSystem Header: Private (2) stream\n");
  710.       }
  711.       break;
  712.     case 0xb1:
  713.       if (streamID < MIN_STREAM_ID_ID) {
  714.     if (opts&SYSLAYER_LOG) {
  715.       fprintf(syslogOutput, "\tSystem Header: Illegal stream ID\n");
  716.       fprintf(syslogOutput, "\tWe believe MPOWER is creating invalid codes here.\n");
  717.     }
  718.     return 1;
  719.       }
  720.       
  721.     default:
  722.       if (streamID < MIN_STREAM_ID_ID) {
  723.     if (opts&SYSLAYER_LOG) {
  724.       fprintf(syslogOutput, "\tSystem Header: Illegal stream ID\n");
  725.     }
  726.     return 1;
  727.       }
  728.       switch (streamID >> 4) {
  729.       case 0xc:
  730.       case 0xd:
  731.     if (opts&SYSLAYER_LOG) {
  732.       fprintf(syslogOutput, "\tSystem Header: audio stream #%d\n",
  733.           (streamID & 0x1f));
  734.     }
  735.     gAudioStreamID = streamID;
  736.     break;
  737.       case 0xe:
  738.     if (opts&SYSLAYER_LOG) {
  739.       fprintf(syslogOutput, "\tSystem Header: video stream #%d\n",
  740.           (streamID & 0xf));
  741.     }
  742.     if ((gVideoStreamID != 0) && (gVideoStreamID!=streamID)) {
  743.       if (opts&SYSLAYER_LOG) {
  744.         fprintf(syslogOutput, 
  745.             "\tThis program can only handle a single video stream\n");
  746.       }
  747.       break;
  748.     }
  749.     gVideoStreamID = streamID;
  750.     break;
  751.       case 0xf:
  752.     gReservedStreamID = streamID;
  753.     if (opts&SYSLAYER_LOG) {
  754.       fprintf(syslogOutput, "S\tystem Header: reserved stream #%d\n",
  755.           (streamID & 0xf));
  756.     }
  757.     break;
  758.       }
  759.       break;
  760.     }
  761.     pos += 3;
  762.   }
  763.   if (inputBuffer != NULL)
  764.     free(inputBuffer);
  765.   return 0;
  766. }
  767.  
  768. /*
  769.  *-----------------------------------------------------------------
  770.  *
  771.  *  ReadPacket
  772.  *
  773.  *      Reads a single packet out of the stream, and puts it in the
  774.  *      buffer if it is video.
  775.  *
  776.  *  Results:
  777.  *      Changes the value of *length_ptr to be the new length (plus old)
  778.  *      If the buffer is too small, can change *bs_ptr, *max_length, and *buf_ptr
  779.  *      to be correct for a newly allocated buffer.
  780.  *
  781.  *  State:  The buffer is in ints, but the packets can be an arbitrary number
  782.  *      of bytes, so leftover bytes are kept in static vars and added in on the
  783.  *      next call.
  784.  *
  785.  *-----------------------------------------------------------------
  786.  */   
  787. int ReadPacket(packetID, bs_ptr, max_length, length_ptr, buf_ptr) 
  788.      unsigned char packetID;
  789.      unsigned int **bs_ptr;
  790.      int *max_length;
  791.      int *length_ptr;
  792.      unsigned int **buf_ptr;
  793.      /* Returns:
  794.     0 - no error, but not video packet we want
  795.     1 - error
  796.     2 - got video packet into buffer
  797.     */
  798. {   
  799.   int ioBytes;
  800.   unsigned char nextByte;
  801.   unsigned short packetLength;
  802.   unsigned char *packetBuffer = NULL;
  803.   int pos;
  804.   int numStuffBytes = 0;
  805.   int packetDataLength;
  806.   int byte_length;
  807.   unsigned char scratch[9];
  808.   int errorCode; /* For syslog */
  809.   /* Leftovers from previous video packets */
  810.   static unsigned int num_left=0, leftover_bytes=0;
  811.   
  812.   if (packetID==NOT_PACKET_ID) {
  813.     /* Gross hack to handle unread bytes before end of stream */
  814.     if (num_left!=0) {
  815.       /* Sigh, deal with previous leftovers */
  816.       *(*buf_ptr+*length_ptr)=leftover_bytes;
  817.       *(*buf_ptr+*length_ptr+1)=ISO_11172_END_CODE;
  818.       *length_ptr+=2;
  819.     } else {
  820.       *(*buf_ptr+*length_ptr)=ISO_11172_END_CODE;
  821.       *length_ptr+=1;
  822.     }
  823.     return 1;
  824.   }
  825.   
  826.   ioBytes = fread(&packetLength, 1, 2, input);
  827.   packetLength=htons(packetLength);
  828.   if (ioBytes < 2) {
  829.     if (opts&SYSLAYER_LOG) {
  830.       fprintf(syslogOutput, "ReadPacket: Error in reading packet length\n");
  831.     }
  832.     return 1;
  833.   }
  834.   if (opts&SYSLAYER_LOG) {
  835.     fprintf(syslogOutput, 
  836.         "\tinput packet with ID %02x has length = %d at file offset %d\n", 
  837.         packetID, packetLength, (int) ftell(input));
  838.   }
  839.   if (packetID == gAudioStreamID) {
  840. #ifdef ANALYSIS
  841.     ++gNumAudioPackets;
  842. #endif
  843.   }
  844.   else if (packetID == gVideoStreamID) {
  845. #ifdef ANALYSIS     
  846.     ++gNumVideoPackets;
  847. #endif
  848.   }
  849.   else {
  850.     switch (packetID) {
  851.     case PADDING_STREAM_ID:
  852.       if (opts&SYSLAYER_LOG) {
  853.     fprintf(syslogOutput, "\tPadding packet.\n");
  854.       }
  855. #ifdef ANALYSIS
  856.       ++gNumPaddingPackets;
  857. #endif
  858.       break;
  859.     case RESERVED_STREAM_ID:
  860.       if (opts&SYSLAYER_LOG) {
  861.     fprintf(syslogOutput, "\tReserved packet.\n");
  862.       }
  863. #ifdef ANALYSIS
  864.       ++gNumReservedPackets;
  865. #endif
  866.       break;
  867.     case PRIVATE_STREAM_1_ID:
  868.       if (opts&SYSLAYER_LOG) {
  869.     fprintf(syslogOutput, "\tPrivate packet type 1.\n");
  870.       }
  871. #ifdef ANALYSIS
  872.       ++gNumPrivate_1_Packets;
  873. #endif
  874.       break;
  875.     case PRIVATE_STREAM_2_ID:
  876.       if (opts&SYSLAYER_LOG) {
  877.     fprintf(syslogOutput, "\tPrivate packet type 2.\n");
  878.       }
  879. #ifdef ANALYSIS
  880.       ++gNumPrivate_2_Packets;
  881. #endif
  882.       break;
  883.     default:
  884.       fprintf(stderr, "\nUnknown packet type encountered. P'bly audio? (%x) at %d\n",
  885.           packetID,(int) ftell(input));
  886.       if (opts&SYSLAYER_LOG) {
  887.     fprintf(syslogOutput,"\tUnknown packet type encountered. P'bly audio. (%x), length %d at offset %d.\n",
  888.         packetID,packetLength,(int) ftell(input));
  889.     fflush(syslogOutput);
  890.       }
  891.     }
  892.     if (opts&SYSLAYER_LOG) {
  893.       fprintf(syslogOutput, "\tSkipping over this packet.\n");
  894.     }
  895.     fseek(input, packetLength, 1);
  896.     sysBytes+=packetLength;
  897.     return 0;
  898.   }
  899.   fread(&nextByte,1,1,input);
  900.   pos = 0;
  901.   while (nextByte & 0x80) {
  902.     ++numStuffBytes;
  903.     if (opts&SYSLAYER_LOG) {
  904.       if (nextByte != 0xff)
  905.     fprintf(syslogOutput, "\tWarning: stuffing byte = 0x%x not 0xff\n", 
  906.         (int)nextByte);
  907.     }
  908.     ++pos;
  909.     fread(&nextByte,1,1,input);
  910.   }
  911.   if (numStuffBytes > 0)
  912.     if (opts&SYSLAYER_LOG) {
  913.       fprintf(syslogOutput, "\tSkipped %d stuffing bytes\n", numStuffBytes);
  914.     }
  915.   if ((nextByte >> 6) == 0x01) {
  916.     pos += 2;
  917.     fread(&nextByte,1,1,input);
  918.     fread(&nextByte,1,1,input);
  919.   } 
  920.   if ((nextByte >> 4) == 0x02) {
  921.     fread(scratch,1,4,input);
  922.     fread(&nextByte,1,1,input);
  923.     pos+=5;
  924.   }
  925.   else if ((nextByte >> 4) == 0x03) {
  926.     fread(scratch,1,9,input);
  927.     fread(&nextByte,1,1,input);
  928.     pos += 10;
  929.   } 
  930.   else {
  931.     if (opts&SYSLAYER_LOG) {
  932.       fprintf(syslogOutput, "\tRead 0x%02x (s.b. 0x0f)\n", nextByte);
  933.     }
  934.     fread(&nextByte,1,1,input);
  935.     pos += 1;
  936.   }
  937.   /* Read all the headers, now make room for packet */
  938.   if (*bs_ptr+*max_length<*buf_ptr+packetLength/4+*length_ptr) {
  939.     if (opts&SYSLAYER_LOG) {
  940.       fprintf(syslogOutput, "\tProblems with buffer length! %d %d\n",
  941.           *max_length-*length_ptr,packetLength/4);
  942.     }
  943.     if (*max_length-*length_ptr<packetLength/4) {
  944.       /* Buffer too small for a packet (plus whats there),
  945.      time to enlarge it! */
  946.       unsigned int *old=*bs_ptr;
  947.       if (opts&SYSLAYER_LOG) {
  948.     fprintf(syslogOutput,"\tMega Resize! old=%d, new=%d\n",
  949.         *max_length,*length_ptr + packetLength/2);
  950.       }
  951.       *max_length = *length_ptr + packetLength/2;
  952.       *bs_ptr=(unsigned int *)malloc(*max_length*4);
  953.       if (*bs_ptr == NULL) {
  954.     if (opts&SYSLAYER_LOG) {
  955.       fprintf(syslogOutput, "\tReadPacket: Error in allocating %d bytes\n",
  956.           *max_length);
  957.     }
  958.     return 1;
  959.       }
  960.       memcpy((unsigned char *)*bs_ptr,*buf_ptr,*length_ptr*4);
  961.       free(old);
  962.       *buf_ptr=*bs_ptr;
  963.     } else {
  964.       memcpy((unsigned char *)*bs_ptr,*buf_ptr,*length_ptr*4);
  965.       *buf_ptr = *bs_ptr;
  966.     }}
  967.   byte_length=*length_ptr*4;
  968.   if (num_left!=0) {
  969.     /* Sigh, deal with previous leftovers */
  970.     byte_length += num_left;
  971.     *(*buf_ptr+*length_ptr)=leftover_bytes;
  972.   }
  973.   packetBuffer=((unsigned char *)*buf_ptr)+byte_length;
  974.   packetDataLength = packetLength - pos;
  975.   *packetBuffer++=nextByte;
  976.   if (packetID == gVideoStreamID) {
  977.     ioBytes=fread(packetBuffer, 1, packetDataLength-1, input);
  978.     if (ioBytes!=packetDataLength-1) {
  979.       EOF_flag=1;
  980.       if (opts&SYSLAYER_LOG) {
  981.     fprintf(syslogOutput,"\tEOF in middle of packet!\n");
  982.       }
  983.       return 1;
  984.     }
  985.     if (opts&SYSLAYER_LOG) {
  986.       fprintf(syslogOutput, "\tKeeping Video packet of length %d (%%=%d)\n",
  987.               packetDataLength,packetDataLength%4);
  988.     }
  989.     if (1!=ntohl(1)) {
  990.       unsigned int *mark=*buf_ptr+*length_ptr;
  991.       int i;
  992.       
  993.       for (i=0; i < ((packetDataLength+num_left)&0xfffffffc); i+=4) {
  994.     *mark=ntohl(*mark);
  995.     mark++;
  996.       }}
  997.     byte_length = byte_length+packetDataLength;
  998.     num_left=byte_length%4;
  999.     *length_ptr = byte_length/4;
  1000.     leftover_bytes = *(*buf_ptr+*length_ptr);
  1001.     sysBytes+=packetLength-packetDataLength;
  1002.     vidBytes+=packetDataLength;
  1003.     return 2;
  1004.   }
  1005.   else if (packetID == gAudioStreamID) { 
  1006.     sysBytes+=packetLength-packetDataLength;
  1007.     audBytes+=packetDataLength;
  1008.     packetBuffer=(unsigned char *)(*buf_ptr+*length_ptr+1);
  1009.     fread(packetBuffer, 1, packetDataLength-1, input);
  1010.     if (opts&SYSLAYER_LOG) {
  1011.       fprintf(syslogOutput, "\tReceived Audio packet of length %d\n",
  1012.           packetDataLength);
  1013.     }
  1014.   }
  1015.   else /* Donno what it is, just nuke it */ {
  1016.     /* This code should be unreachable */
  1017.     sysBytes+=packetLength;
  1018.     packetBuffer=(unsigned char *)(*buf_ptr+*length_ptr+1);
  1019.     fread(packetBuffer, 1, packetDataLength-1, input);
  1020.     if (opts&SYSLAYER_LOG) {
  1021.       fprintf(syslogOutput, "\tReceived Unknown packet of length %d\n",
  1022.           packetDataLength);
  1023.     }
  1024.   }
  1025.   return 0; 
  1026. }
  1027.  
  1028.  
  1029. /*
  1030.  * The remaining procedures are formatting utility procedures.
  1031.  */
  1032. void ReadTimeStamp(inputBuffer,hiBit,low4Bytes)
  1033.      unsigned char *inputBuffer, *hiBit;
  1034.      unsigned long *low4Bytes;
  1035. {
  1036.   *hiBit = ((unsigned long)inputBuffer[0] >> 3) & 0x01;
  1037.   *low4Bytes = (((unsigned long)inputBuffer[0] >> 1) & 0x03) << 30; 
  1038.   *low4Bytes |= (unsigned long)inputBuffer[1] << 22; 
  1039.   *low4Bytes |= ((unsigned long)inputBuffer[2] >> 1) << 15; 
  1040.   *low4Bytes |= (unsigned long)inputBuffer[3] << 7; 
  1041.   *low4Bytes |= ((unsigned long)inputBuffer[4]) >> 1; 
  1042. }
  1043.  
  1044. void ReadSTD(
  1045.          unsigned char *inputBuffer,
  1046.          unsigned char *stdBufferScale,
  1047.          unsigned long *stdBufferSize) 
  1048. {
  1049.   *stdBufferScale = ((inputBuffer[0] & 0x20) >> 5); 
  1050.   *stdBufferSize = ((unsigned long)inputBuffer[0] & 0x1f) << 8;
  1051.   *stdBufferSize |= (unsigned long)inputBuffer[1];
  1052. }
  1053.  
  1054.  
  1055. void ReadRate(inputBuffer,rate)
  1056.      unsigned char *inputBuffer;
  1057.      unsigned long *rate;
  1058. {
  1059.   *rate = (inputBuffer[0] & 0x7f) << 15;
  1060.   *rate |= inputBuffer[1] << 7;
  1061.   *rate |= (inputBuffer[2] & 0xfe) >> 1;
  1062. }
  1063.  
  1064. #define FLOAT_0x10000 (double)((unsigned long)1 << 16)
  1065.  
  1066. int MakeFloatClockTime(hiBit,low4Bytes,floatClockTime)
  1067.      unsigned char hiBit;
  1068.      unsigned long low4Bytes;
  1069.      double *floatClockTime;
  1070. {
  1071.   if (hiBit != 0 && hiBit != 1) {
  1072.     *floatClockTime = 0.0;
  1073.     return 1;
  1074.   }
  1075.   *floatClockTime 
  1076.     = (double)hiBit*FLOAT_0x10000*FLOAT_0x10000 + (double)low4Bytes;
  1077.   *floatClockTime /= (double)STD_SYSTEM_CLOCK_FREQ;
  1078.   return 0;
  1079. }
  1080.